﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using WmsService.Exceptions;
using WmsService.Factory;
using WmsService.In;

namespace WmsService
{
    public partial class Service
    {
        #region PayType

        public List<PayType> GetPayTypes()
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();
                var q = from c in ctx.PayType
                        select c;
                return q.ToList();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public void SavePayTypes(List<PayType> list)
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();

                foreach (var payType in list)
                {
                    ctx.AddToPayType(payType);
                    ctx.ObjectStateManager.ChangeObjectState(payType, payType.WcfEntityState);
                }
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
            }
        }

        #endregion

        #region PayApplyBill

        public List<PayApplyBill> GetPayApplyBills()
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();
                var q = from c in ctx.PayApplyBill
                        select c;
                return q.ToList();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public List<PayApplyBill> GetPayApplyBillsByCondition(string condition)
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();
                return
                    ctx.ExecuteStoreQuery<PayApplyBill>("select * from  dbo.PayApplyBill where  1=1 " + condition).
                        ToList();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public string GetPayApplyBillID()
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();
                return ctx.ExecuteStoreQuery<String>("select dbo.GetPayApplyBillID() as BillID").FirstOrDefault();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }


        public void SavePayApplyBills(List<PayApplyBill> list)
        {
            throw new NotImplementedException();
        }

        public PayApplyBill GetPayApplyBill(string payApplyBillID)
        {
            var ctx = ContextFactory.Create();
            var q = from c in ctx.PayApplyBill
                    where c.PayApplyBillID == payApplyBillID
                    select c;
            var list = q.ToList();
            if (list.Count == 0)
                return null;
            else
            {
                ctx.Detach(list[0]);
                return list[0];
            }
        }

        #endregion

        #region PayApplyBillDtl

        public List<PayApplyBillDtl> GetPayApplyBillDtls()
        {
            try
            {
                //IAuthenticationFactory.GetAuthentication().ValidateToken(this.GetContextToken());
                var ctx = ContextFactory.Create();
                var q = from c in ctx.PayApplyBillDtl
                        select c;
                return q.ToList();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public PayApplyBillDtl GetPayApplyBillDtl(string payApplyBillID, string invoiceNo)
        {
            var ctx = ContextFactory.Create();
            var q = from c in ctx.PayApplyBillDtl
                    where c.PayApplyBillID == payApplyBillID
                          && c.InvoiceNo == invoiceNo
                    select c;
            var list = q.ToList();
            if (list.Count == 0)
                return null;
            ctx.Detach(list[0]);
            return list[0];
        }

        public List<PayApplyBillDtl> GetPayApplyBillDtlsByCondition(string condition)
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();
                return
                    ctx.ExecuteStoreQuery<PayApplyBillDtl>("select * from  dbo.PayApplyBillDtl where  1=1 " + condition)
                        .ToList();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public void SavePayApplyBillDtls(List<PayApplyBillDtl> list)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region PayApplyBillWrap

        public PayApplyBillWrap GetPayApplyBillWrap(string billID)
        {
            try
            {
                SecurityValidate();
                var billWrap = new PayApplyBillWrap();
                var ctx = ContextFactory.Create();
                var q = from c in ctx.PayApplyBill
                        where c.PayApplyBillID == billID
                        select c;
                var payApplyBill = q.FirstOrDefault();
                if (payApplyBill == null)
                {
                    return null;
                }

                ctx.Detach(payApplyBill);
                billWrap.FPayApplyBill = payApplyBill;
                var q2 = from c in ctx.PayApplyBillDtl
                         where c.PayApplyBillID == billID
                         select c;
                billWrap.FPayApplyBillDtl = q2.ToList();
                foreach (var dtl in billWrap.FPayApplyBillDtl)
                {
                    ctx.Detach(dtl);
                }

                var q3 = from c in ctx.PayApplyBillItem
                         where c.PayApplyBillID == billID
                         orderby c.Idx ascending
                         select c;
                billWrap.FPayApplyBillItem = q3.ToList();
                foreach (var item in billWrap.FPayApplyBillItem)
                {
                    ctx.Detach(item);
                }

                return billWrap;
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return null;
            }
        }

        public void SavePayApplyBillWrap(PayApplyBillWrap payApplyBillWrap)
        {
            try
            {
                SecurityValidate();
                if (payApplyBillWrap.FPayApplyBill.PayApplyState != Constant.BillStateDraft)
                {
                    Exceptions.ExceptionHandler.ThrowException("非草稿状态的付款申请单单不能保存：" + payApplyBillWrap.FPayApplyBill.PayApplyBillID);
                }

                var ctx = ContextFactory.Create();
                if (payApplyBillWrap.FPayApplyBill.WcfEntityState == EntityState.Added)
                {
                    payApplyBillWrap.FPayApplyBill.CREATETIME = DateTime.Now;
                    payApplyBillWrap.FPayApplyBill.UPDATETIME = DateTime.Now;
                    payApplyBillWrap.FPayApplyBill.CREATERUSERID = ContextUserID;
                    payApplyBillWrap.FPayApplyBill.CREATERNAME = ContextUserName;
                    payApplyBillWrap.FPayApplyBill.UPDATERNAME = ContextUserID;
                }
                else
                {
                    payApplyBillWrap.FPayApplyBill.UPDATETIME = DateTime.Now;
                    payApplyBillWrap.FPayApplyBill.UPDATERNAME = ContextUserID;
                }
                ctx.AddToPayApplyBill(payApplyBillWrap.FPayApplyBill);
                ctx.ObjectStateManager.ChangeObjectState(payApplyBillWrap.FPayApplyBill,
                                                         payApplyBillWrap.FPayApplyBill.WcfEntityState);
                if (payApplyBillWrap.FPayApplyBillDtl != null && payApplyBillWrap.FPayApplyBillDtl.Count > 0)
                {
                    foreach (var payApplyBillDtl in payApplyBillWrap.FPayApplyBillDtl)
                    {
                        ctx.AddToPayApplyBillDtl(payApplyBillDtl);
                        ctx.ObjectStateManager.ChangeObjectState(payApplyBillDtl, payApplyBillDtl.WcfEntityState);
                    }
                }
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
            }
        }

        public void AffirmPayApplyBill(string billID)
        {
            try
            {
                SecurityValidate();
                var ctx = ContextFactory.Create();

                var wrap = GetPayApplyBillWrap(billID);

                var payApplyBill = wrap.FPayApplyBill;

                if (payApplyBill.PayApplyState != Constant.BillStateDraft)
                {
                    Exceptions.ExceptionHandler.ThrowException("付款申请单状态为非草稿状态，不能确认：" + billID);
                }

                var list =
                    GetInvoiceBillsByCondition(String.Format("and PayApplyBillID = '{0}'", payApplyBill.PayApplyBillID));

                //foreach (var invoiceBill in list)
                //{
                //    if (invoiceBill.ProviderCode != payApplyBill.ProviderCode)
                //    {
                //    }
                //}
                if (list.Select(i => String.Equals(i.ProviderCode, payApplyBill.ProviderCode)).Count() < list.Count)
                {
                    Exceptions.ExceptionHandler.ThrowException("付款申请单的供应商和发票的供应商不一致，请修改：" + billID);
                }

                payApplyBill.PayApplyState = Constant.BillStateAffirm; //状态为确认
                payApplyBill.PayState = Constant.PayNone;
                payApplyBill.UPDATERNAME = ContextUserID;
                payApplyBill.UPDATETIME = DateTime.Now;

                ctx.AddToPayApplyBill(payApplyBill);
                ctx.ObjectStateManager.ChangeObjectState(payApplyBill, EntityState.Modified);
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
            }
        }

        #endregion

        #region Update

        public List<UpdateList> GetAllAssemblyVersions()
        {
            var ctx = ContextFactory.Create();
            var query = from o in ctx.UpdateList
                        select o;
            return query.ToList();
        }

        public List<Byte[]> GetBytesByAssemblyName(List<String> names)
        {
            var path = ConfigurationManager.AppSettings["updateDllPath"];
            var list = new List<byte[]>();
            foreach (var name in names)
            {
                list.Add(File.ReadAllBytes(path + "\\" + name));
            }
            return list;
        }

        public int PublishFile(string tFileName, Byte[] bytes)
        {
            try
            {
                SecurityValidate();
                var administratorUserID = ConfigurationManager.AppSettings["AdministratorUserID"];
                if (administratorUserID == null) throw new NotImplementedException("服务器配置中AdministratorUserID节点没有配置！");

                if (String.IsNullOrEmpty(administratorUserID))
                {
                    administratorUserID = "admin";
                }
                if (ContextUserID != administratorUserID)
                {
                    Exceptions.ExceptionHandler.ThrowException("只有管理员才能发布更新文件！");
                }
                var ctx = ContextFactory.Create();
                var query = from o in ctx.UpdateList
                            where o.TFileName == tFileName
                            select o;
                var list = query.ToList();
                var resultVersion = 0;
                if (list.Count == 0)
                {
                    var ul = ctx.UpdateList.CreateObject();
                    ul.TFileName = tFileName;
                    ul.TLastUpdateTime = DateTime.Now;
                    ul.TPublishUserID = ContextUserID;
                    ul.TPublishUserName = ContextUserName;
                    ul.TVersion = 1;
                    resultVersion = 1;
                    ctx.AddToUpdateList(ul);
                    ctx.ObjectStateManager.ChangeObjectState(ul, EntityState.Added);
                }
                else
                {
                    ctx.Detach(list[0]);
                    var ul = list[0];
                    ul.TLastUpdateTime = DateTime.Now;
                    ul.TPublishUserID = ContextUserID;
                    ul.TPublishUserName = ContextUserName;
                    ul.TVersion = ul.TVersion + 1;
                    resultVersion = ul.TVersion;
                    ctx.AddToUpdateList(ul);
                    ctx.ObjectStateManager.ChangeObjectState(ul, EntityState.Modified);
                }
                ctx.SaveChanges();
                var path = ConfigurationManager.AppSettings["updateDllPath"];
                File.WriteAllBytes(path + "\\" + tFileName, bytes);
                return resultVersion;
            }
            catch (Exception ex)
            {
                ExceptionHandler.ThrowException(ex);
                return 0;
            }
        }

        #endregion
    }
}